home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2000 January / Macworld (2000-01).dmg / Shareware World / Utilities / Text processing / PDF–Blit™1.02.sea / PDF–Blit™1.02 / Source / pdfOutput.c < prev    next >
C/C++ Source or Header  |  1999-09-17  |  24KB  |  970 lines

  1. // ©1999 by Kas Thomas. All rights reserved. See ReadMe for important information.
  2. #include <A4Stuff.h>
  3. #include <MacTypes.h>
  4. #include <Aliases.h>
  5. #include <string.h>
  6. #include <ExternalInterface.h>
  7. #include <BBXTInterface.h>
  8. #include "p_intern.h"
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include "p_afmparse.h"
  12. #include "pdfPrefs.h"
  13. #include <math.h>
  14. #define    ExternalCallbackBlock    BBXTCallbackBlock
  15. #define ITALIC 0x0002
  16. #define BOLDFACE 0x0001
  17. #define NOT_ITALIC 0xFFFD
  18. #define NOT_BOLDFACE 0xFFFE
  19. #define SPACE 0x20
  20. #define LINEFEED 0x0a 
  21. #define FONTSIZE 9
  22. #define LEADING 10.0
  23. #define TEXT_STARTX 60
  24. #define TEXT_STARTY 750
  25. #define LINES_PER_PAGE 60
  26. #define CARRIAGE_RETURN 0x0d
  27. #define TAB 0x09
  28. #define LETTER_WIDTH letter_width
  29. #define LETTER_HEIGHT letter_height
  30. #define TAB_VALUE 5
  31. #define PAGEWIDTH (8.5 * 72)
  32. #define PAGEHEIGHT (11.5 * 72)
  33.  
  34. OSErr pdfTranslate(ExternalCallbackBlock *cb, Handle t, WindowPtr w );
  35. void FudgeName(ExternalCallbackBlock *cb, unsigned char *str, WindowPtr w);
  36. pascal OSErr main(ExternalCallbackBlock *callbacks, 
  37.     WindowPtr w, long flags, AppleEvent *event, AppleEvent *reply);
  38. void setDefaultPrefs( PrefsPtr p );
  39. void JustifyLine(PDF *p, char *line, PrefsPtr pp,long targetWidth);
  40. int CountWords(char *line);
  41. int CountChars(char *line);
  42. void DoHeader(PrefsPtr prefs, PDF *p, long page);
  43. void OpenInAcrobat(ExternalCallbackBlock *cb,WindowPtr w, char *pdfFileName);
  44. float InterpretHTML(PDF *p, char *line, PrefsPtr pp, long *i);
  45. void SetStyle(PDF *p, PrefsPtr prefs);
  46. char *lowerstr( char *p);
  47. int Hex2int(char *c);
  48. void SetTextColor(PDF *p, PrefsPtr prefs );
  49. float LeadingValue(PDF *p,PrefsPtr prefs);
  50. char *fontTable[] = { "","Helvetica","Helvetica-Bold","Helvetica-Oblique","Helvetica-BoldOblique",
  51. "Times-Roman","Times-Bold","Times-Italic","Times-BoldItalic","Courier","Courier-Bold","Courier-Oblique","Courier-BoldOblique"};
  52. char *transitionsTable[] = { "","wipe","dissolve","box","split","blinds","replace","glitter"};
  53.         
  54. unsigned char buf[1024];
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61. // * * * * * * * * * * * * * * main() * * * * * * * * * * * * * * * * 
  62. pascal OSErr main(ExternalCallbackBlock *callbacks, 
  63.     WindowPtr w, long flags, AppleEvent *event, AppleEvent *reply)
  64. {
  65.     OSErr    err = noErr;
  66.     EnterCodeResource();
  67.     {
  68.         Handle text;
  69.         WindowPtr newWindow;
  70.         
  71.         if (!w) return err;
  72.     
  73.         text = bbxtGetWindowContents(callbacks,w);
  74.     
  75.         err = pdfTranslate(callbacks,text,w); 
  76.     } 
  77. ExitCodeResource();
  78. return err;
  79. }
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86. OSErr pdfTranslate( ExternalCallbackBlock *callbacks, 
  87. Handle theText,
  88. WindowPtr w ) {
  89. PDF *p=nil;
  90. int font,j;
  91. long i,textLength;
  92. OSErr err = noErr;
  93. Boolean timeForNewPage = false; 
  94. char okLineEnders[] = "- ;:,";
  95. PrefsPtr prefs = nil;
  96. unsigned char *input,filename[32];
  97. unsigned char *out = buf;
  98. short nuts,vRef,fref = -1;
  99. long DirID,amt;
  100. FSSpec fss;
  101. long page = 1L;
  102. float currentDepth,pointDepthLimit;
  103. int origBaseFont;
  104. prefs = (PrefsPtr)NewPtr(sizeof(Prefs));
  105. err = FindFolder(kOnSystemDisk,kPreferencesFolderType,true,&vRef,&DirID);
  106. err = FSMakeFSSpec(vRef,DirID,"\pPDF-Blit 1.0 Prefs",&fss);
  107. err = FSpOpenDF(&fss,fsRdWrPerm,&fref);
  108. if (err) {
  109. err = FSpCreate(&fss,'pdfK','TEXT',smSystemScript);
  110. if (err) return err;
  111. setDefaultPrefs( prefs);
  112. err = FSpOpenDF(&fss,fsRdWrPerm,&fref);
  113. }
  114. else {
  115. amt = sizeof(Prefs);
  116. err = FSRead(fref, &amt, prefs);
  117. if (err || !amt)
  118. setDefaultPrefs( prefs);
  119. }
  120. prefs->color[0] = prefs->color[1] = prefs->color[2] = 0.0;
  121. prefs->style = 0;
  122. if (-1 == DoDialog(callbacks, prefs)) {
  123. if (prefs) DisposePtr((Ptr)prefs);
  124. if (fref != -1) FSClose(fref);
  125. return err;
  126. }
  127. p = PDF_new(); 
  128. if (p == nil) { 
  129. return -1;
  130. }
  131. HLockHi(theText);
  132. textLength = GetHandleSize(theText);
  133. FudgeName(callbacks,filename,w);
  134. if (PDF_open_file(p,(char *)filename )==-1){
  135. ParamText("\pProblem opening the output file.","\p ","\p","\p");
  136. NoteAlert(401,0);
  137. return err;
  138. }
  139. PDF_set_info(p,"Creator","PDFOut 1.0");
  140. PDF_set_info(p,"Author",(char *)prefs->author);
  141. PDF_set_info(p,"Title",(char *)prefs->title);
  142. PDF_set_info(p,"Keywords",(char *)prefs->keywords);
  143. PDF_set_transition(p,(char *)transitionsTable[prefs->transition]);
  144. PDF_begin_page(p,letter_width,letter_height); 
  145. font = PDF_findfont(p,(char *)fontTable[ prefs->font ],"default",0);
  146. if (font ==-1){
  147. fprintf(stderr,"Couldn't set font!\n");
  148. HUnlock(theText);
  149. exit(3);
  150. }
  151. PDF_setfont(p,font,prefs->ptsize);
  152. PDF_set_leading(p, prefs->leading);
  153. PDF_show(p," ");
  154. origBaseFont = prefs->font;
  155. pointDepthLimit = PAGEHEIGHT - prefs->marginBot;
  156. DoHeader(prefs,p,page);
  157. currentDepth = prefs->marginTop + LeadingValue(p,prefs);
  158. PDF_set_text_pos(p,prefs->marginLeft,PAGEHEIGHT-currentDepth);
  159. bbxtStartProgress(callbacks,"\p Writing PDF... Thank you for using PDF–Blit!",textLength,true);
  160. input = *(unsigned char **)theText;
  161. if (prefs->marginLeft + prefs->marginRt > PAGEWIDTH) goto TheEnd;
  162. if (prefs->marginTop + prefs->marginBot > PAGEHEIGHT) goto TheEnd;
  163. for (i = 0; i < textLength - 1 ; ) 
  164. Boolean LineSegmented = false;
  165. float lw = 0.,soFar = 0.;
  166. int ourFont = PDF_get_font(p);
  167. long desiredWidth = (long)(PAGEWIDTH - (prefs->marginLeft + prefs->marginRt));
  168. if (prefs->justify == false)
  169. desiredWidth -= 0.5 * prefs->marginRt;
  170. if (bbxtDoProgress(callbacks,i)) 
  171. goto TheEnd;
  172.  
  173. for (j = 0, out = buf, *(out+1)=0x00; 
  174. (lw < desiredWidth) && i < textLength - 1; 
  175. j++) 
  176. if (j == 0) 
  177. if (input[i] == SPACE) {
  178. while (input[i] == SPACE) 
  179. i++;
  180. continue;
  181. }
  182. PDF_set_horiz_scaling(p,(float)prefs->chwidth);
  183. *out++ = input[i++];
  184.  
  185. if (prefs->interpHTML == true ) {
  186.  
  187. if (input[i-1] == '<' && input[i-2] == 0x5c) {
  188. *(out - 2) = *(out - 1); 
  189. out--;
  190. else if (input[i-1] == '<' && input[i-2] != 0x5c) 
  191. {
  192. Boolean sendDown = (input[i-2] == CARRIAGE_RETURN) ? true:false;
  193. float fsize = PDF_get_fontsize(p);
  194. int currentFont = PDF_get_font(p);
  195. if (input[i] == 'h' || input[i] == 'H') {
  196. char *range = "123456";
  197. char ch = input[i+1];
  198.  
  199. if (strchr(range,ch) != NULL) {
  200. int fnt = PDF_findfont(p,(char *)fontTable[6],"default",0);
  201. if (LineSegmented == false) 
  202. {
  203. currentDepth += LeadingValue(p,prefs);
  204. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  205. }
  206. LineSegmented = true; 
  207. if (ch == '1') fsize *= 1.1 * 1.1 * 1.1 * 1.1 * 1.2 * 1.2;
  208. if (ch == '2') fsize *= 1.1 * 1.1 * 1.1 * 1.1 * 1.2;
  209. if (ch == '3') fsize *= 1.1 * 1.1 * 1.1 * 1.1;
  210. if (ch == '4') fsize *= 1.1 * 1.1 * 1.1;
  211. if (ch == '5') fsize *= 1.1 * 1.1;
  212. if (ch == '6') fsize *= 1.1;
  213.  
  214. *(out - 1)=0x00;
  215. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  216. PDF_show(p,(char *)buf);
  217. PDF_setfont(p, fnt, fsize );
  218. PDF_set_leading(p,fsize); 
  219. out = buf;
  220. *out++ = input[i]; 
  221.  
  222. if (tolower(input[i]) == 'p' && 
  223. tolower(input[i+1]) == 'r' && 
  224. tolower(input[i+2]) == 'e') 
  225. {
  226. if (LineSegmented == false) 
  227. {
  228. currentDepth += LeadingValue(p,prefs);
  229. PDF_set_text_pos(p,(float)(prefs->marginLeft),
  230. PAGEHEIGHT-currentDepth);
  231. }
  232. LineSegmented = true;
  233. *(out - 1)=0x00;
  234. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  235. PDF_show(p,(char *)buf);
  236. out = buf;
  237. *out++ = input[i]; 
  238. prefs->font = 9; 
  239. SetStyle(p,prefs);
  240. }
  241.  
  242. if (input[i] == 'i' || input[i] == 'I') 
  243. if (input[i+1] != 'm' && input[i+1] != 'M') {
  244. if (LineSegmented == false) 
  245. {
  246. currentDepth += LeadingValue(p,prefs);
  247. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  248. }
  249. LineSegmented = true;
  250. *(out - 1)=0x00;
  251. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  252. PDF_show(p,(char *)buf);
  253. out = buf;
  254. *out++ = input[i]; 
  255. prefs->style |= ITALIC;
  256. SetStyle(p,prefs);
  257. }
  258.  
  259.  
  260. if (tolower(input[i]) == 'b' || !strncmp("strong",(char *)(input+i),6) ||
  261. !strncmp("STRONG",(char *)(input+i),6)) 
  262. {
  263. if (LineSegmented == false) 
  264. {
  265. currentDepth += LeadingValue(p,prefs);
  266. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  267. }
  268. LineSegmented = true;
  269. *(out - 1)=0x00;
  270. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  271. PDF_show(p,(char *)buf);
  272. out = buf;
  273. *out++ = input[i]; 
  274. prefs->style |= BOLDFACE;
  275. SetStyle(p,prefs);
  276. }
  277.  
  278. if (!strncmp("rect",(char *)(input+i),4) ||
  279. !strncmp("RECT",(char *)(input+i),4) )
  280. {
  281. char *st,*ch = (char *) input + i + 4;
  282. float left,bottom,width,height;
  283.  
  284. while (*ch == SPACE) ch++; 
  285. st = ch;
  286. while (isdigit(*ch) || *ch == '.') ch++;
  287. *ch = 0x00;
  288. left = (float) atoi(st); 
  289. *ch = SPACE;
  290.  
  291. while (*ch == SPACE || *ch == 0x00) ch++; 
  292. st = ch;
  293. while (isdigit(*ch) || *ch == '.') ch++;
  294. *ch = 0x00;
  295. bottom = (float) atoi(st);
  296. *ch = SPACE;
  297.  
  298. while (*ch == SPACE || *ch == 0x00) ch++; 
  299. st = ch;
  300. while (isdigit(*ch) || *ch == '.') ch++;
  301. *ch = 0x00;
  302. width = (float) atoi(st);
  303. *ch = SPACE;
  304.  
  305. while (*ch == SPACE || *ch == 0x00) ch++; 
  306. st = ch;
  307. while (isdigit(*ch) || *ch == '.') ch++;
  308. { char old = *ch;
  309. *ch = 0x00;
  310.  
  311. height = (float) atoi(st);
  312. *ch = old;
  313. }
  314. PDF_save(p);
  315. PDF_rect(p,left,bottom,width,height);
  316. PDF_fill(p);
  317. PDF_restore(p);
  318. }
  319.  
  320. if (!strncmp("font color=#",(char *)(input+i),12) ||
  321. !strncmp("FONT COLOR=#",(char *)(input+i),12) )
  322. {
  323. float r,g,b;
  324. int j;
  325. char ch[3];
  326. if (LineSegmented == false) 
  327. {
  328. currentDepth += LeadingValue(p,prefs);
  329. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  330. }
  331. LineSegmented = true;
  332. *(out - 1)=0x00;
  333. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  334. PDF_show(p,(char *)buf);
  335. out = buf;
  336. *out++ = input[i]; 
  337. ch[0] = input[i+13]; ch[1] = input[i+14]; ch[2] = 0x00;
  338. j = Hex2int(ch); 
  339. r = (float)j/255.;
  340. ch[0] = input[i+15]; ch[1] = input[i+16]; ch[2] = 0x00;
  341. j = Hex2int(ch); 
  342. g = (float)j/255.;
  343. ch[0] = input[i+17]; ch[1] = input[i+17]; ch[2] = 0x00;
  344. j = Hex2int(ch); 
  345. b = (float)j/255.;
  346. prefs->color[0] = r;
  347. prefs->color[1] = g;
  348. prefs->color[2] = b;
  349. SetTextColor(p,prefs);
  350. }
  351.  
  352. if (input[i] == '!' && input[i+1] == '!')
  353. {
  354. out--;
  355. i--;
  356. while (input[i++] != '>') ;
  357. currentDepth = pointDepthLimit;
  358. goto NewPage; 
  359.  
  360. if (input[i] == '#' && input[i + 1] == '3' && input[i+2] == '0')
  361. goto TheEnd;
  362.  
  363. if (input[i] == 0x2f) 
  364. {
  365. if (input[i+1]=='h' || input[i+1]=='H') {
  366. if (LineSegmented == false) 
  367. {
  368. currentDepth += LeadingValue(p,prefs);
  369. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  370. }
  371. LineSegmented = true;
  372. *(out - 1)=0x00;
  373. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  374. PDF_show(p,(char *)buf);
  375. out = buf;
  376. *out++ = input[i]; 
  377. PDF_set_leading (p, prefs->leading);
  378. PDF_setfont(p,font,prefs->ptsize);
  379.  
  380. if (tolower(input[i+1])=='p' && tolower(input[i+2])=='r'
  381. && tolower(input[i+3])=='e')
  382. {
  383. if (LineSegmented == false) 
  384. {
  385. currentDepth += LeadingValue(p,prefs);
  386. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  387. }
  388. LineSegmented = true;
  389. *(out - 1)=0x00;
  390. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  391. PDF_show(p,(char *)buf);
  392. out = buf;
  393. *out++ = input[i]; 
  394. prefs->font = origBaseFont;
  395. SetStyle(p,prefs);
  396. }
  397.  
  398. if (input[i+1]=='i' || input[i+1]=='I') {
  399. if (LineSegmented == false) 
  400. {
  401. currentDepth += LeadingValue(p,prefs);
  402. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  403. }
  404. LineSegmented = true;
  405. *(out - 1)=0x00;
  406. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  407. PDF_show(p,(char *)buf);
  408. out = buf;
  409. *out++ = input[i]; 
  410. prefs->style &= NOT_ITALIC;
  411. SetStyle(p,prefs);
  412. }
  413.  
  414. if (tolower(input[i+1])=='b' || !strncmp("strong",(char *)(input+i+1),6)
  415. || !strncmp("STRONG",(char *)(input+i+1),6)) {
  416. if (LineSegmented == false) 
  417. {
  418. currentDepth += LeadingValue(p,prefs);
  419. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  420. }
  421. LineSegmented = true;
  422. *(out - 1)=0x00;
  423. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  424. PDF_show(p,(char *)buf);
  425. out = buf;
  426. *out++ = input[i]; 
  427. prefs->style &= NOT_BOLDFACE;
  428. SetStyle(p,prefs);
  429. }
  430. out--;
  431. i--;
  432. while (input[i++] != '>') ;
  433.  
  434. if (sendDown == true)
  435. goto TerminateLine;
  436. continue;
  437.  
  438.  
  439. if (input[i-1] == TAB) { 
  440. int k;
  441. for (k = 0; k < prefs->spaces; k++)
  442. *out++ = SPACE;
  443. }
  444. *out = 0x00;
  445. lw = PDF_stringwidth(p,(char *)buf,ourFont,prefs->ptsize) + soFar;
  446. lw *= prefs->chwidth/100.; 
  447. if (input[i-1] == CARRIAGE_RETURN || LINEFEED == input[i-1]) { 
  448. if (LineSegmented == true)
  449. { PDF_show(p,(char *)buf); goto SegEntry; }
  450. else goto TerminateLine;
  451. }
  452. do {
  453. if (prefs->interpHTML == true ) 
  454. {
  455. if (input[i-1] == '<' && input[i-2] != 0x5c) 
  456. {
  457. out--;
  458. i--;
  459. while (input[i++] != '>') ;
  460. }
  461. *out++ = input[i++];
  462.  
  463. if (prefs->interpHTML == true ) {
  464.  
  465. if (input[i-1] == '<' && input[i-2] == 0x5c) {
  466. *(out - 2) = *(out - 1); 
  467. out--;
  468. else if (input[i-1] == '<' && input[i-2] != 0x5c) 
  469. {
  470. Boolean sendDown = (input[i-2] == CARRIAGE_RETURN) ? true:false;
  471. float fsize = PDF_get_fontsize(p);
  472. int currentFont = PDF_get_font(p);
  473. if (input[i] == 'h' || input[i] == 'H') {
  474. char *range = "123456";
  475. char ch = input[i+1];
  476.  
  477. if (strchr(range,ch) != NULL) {
  478. int fnt = PDF_findfont(p,(char *)fontTable[6],"default",0);
  479. if (LineSegmented == false) 
  480. {
  481. currentDepth += LeadingValue(p,prefs);
  482. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  483. }
  484. LineSegmented = true; 
  485. if (ch == '1') fsize *= 1.1 * 1.1 * 1.1 * 1.1 * 1.2 * 1.2;
  486. if (ch == '2') fsize *= 1.1 * 1.1 * 1.1 * 1.1 * 1.2;
  487. if (ch == '3') fsize *= 1.1 * 1.1 * 1.1 * 1.1;
  488. if (ch == '4') fsize *= 1.1 * 1.1 * 1.1;
  489. if (ch == '5') fsize *= 1.1 * 1.1;
  490. if (ch == '6') fsize *= 1.1;
  491.  
  492. *(out - 1)=0x00;
  493. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  494. PDF_show(p,(char *)buf);
  495. PDF_setfont(p, fnt, fsize );
  496. PDF_set_leading(p,fsize); 
  497. out = buf;
  498. *out++ = input[i]; 
  499.  
  500. if (tolower(input[i]) == 'p' && 
  501. tolower(input[i+1]) == 'r' && 
  502. tolower(input[i+2]) == 'e') 
  503. {
  504. if (LineSegmented == false) 
  505. {
  506. currentDepth += LeadingValue(p,prefs);
  507. PDF_set_text_pos(p,(float)(prefs->marginLeft),
  508. PAGEHEIGHT-currentDepth);
  509. }
  510. LineSegmented = true;
  511. *(out - 1)=0x00;
  512. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  513. PDF_show(p,(char *)buf);
  514. out = buf;
  515. *out++ = input[i]; 
  516. prefs->font = 9; 
  517. SetStyle(p,prefs);
  518. }
  519.  
  520. if (input[i] == 'i' || input[i] == 'I') 
  521. if (input[i+1] != 'm' && input[i+1] != 'M') {
  522. if (LineSegmented == false) 
  523. {
  524. currentDepth += LeadingValue(p,prefs);
  525. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  526. }
  527. LineSegmented = true;
  528. *(out - 1)=0x00;
  529. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  530. PDF_show(p,(char *)buf);
  531. out = buf;
  532. *out++ = input[i]; 
  533. prefs->style |= ITALIC;
  534. SetStyle(p,prefs);
  535. }
  536.  
  537.  
  538. if (tolower(input[i]) == 'b' || !strncmp("strong",(char *)(input+i),6) ||
  539. !strncmp("STRONG",(char *)(input+i),6)) 
  540. {
  541. if (LineSegmented == false) 
  542. {
  543. currentDepth += LeadingValue(p,prefs);
  544. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  545. }
  546. LineSegmented = true;
  547. *(out - 1)=0x00;
  548. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  549. PDF_show(p,(char *)buf);
  550. out = buf;
  551. *out++ = input[i]; 
  552. prefs->style |= BOLDFACE;
  553. SetStyle(p,prefs);
  554. }
  555.  
  556. if (!strncmp("rect",(char *)(input+i),4) ||
  557. !strncmp("RECT",(char *)(input+i),4) )
  558. {
  559. char *st,*ch = (char *) input + i + 4;
  560. float left,bottom,width,height;
  561.  
  562. while (*ch == SPACE) ch++; 
  563. st = ch;
  564. while (isdigit(*ch) || *ch == '.') ch++;
  565. *ch = 0x00;
  566. left = (float) atoi(st); 
  567. *ch = SPACE;
  568.  
  569. while (*ch == SPACE || *ch == 0x00) ch++; 
  570. st = ch;
  571. while (isdigit(*ch) || *ch == '.') ch++;
  572. *ch = 0x00;
  573. bottom = (float) atoi(st);
  574. *ch = SPACE;
  575.  
  576. while (*ch == SPACE || *ch == 0x00) ch++; 
  577. st = ch;
  578. while (isdigit(*ch) || *ch == '.') ch++;
  579. *ch = 0x00;
  580. width = (float) atoi(st);
  581. *ch = SPACE;
  582.  
  583. while (*ch == SPACE || *ch == 0x00) ch++; 
  584. {char old = *ch;
  585. st = ch;
  586. while (isdigit(*ch) || *ch == '.') ch++;
  587. *ch = 0x00;
  588.  
  589. height = (float) atoi(st);
  590. *ch = old;
  591. PDF_save(p);
  592. PDF_rect(p,left,bottom,width,height);
  593. PDF_fill(p);
  594. PDF_restore(p); 
  595.  
  596. }
  597.  
  598. if (!strncmp("font color=#",(char *)(input+i),12) ||
  599. !strncmp("FONT COLOR=#",(char *)(input+i),12) )
  600. {
  601. float r,g,b;
  602. int j;
  603. char ch[3];
  604. if (LineSegmented == false) 
  605. {
  606. currentDepth += LeadingValue(p,prefs);
  607. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  608. }
  609. LineSegmented = true;
  610. *(out - 1)=0x00;
  611. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  612. PDF_show(p,(char *)buf);
  613. out = buf;
  614. *out++ = input[i]; 
  615. ch[0] = input[i+13]; ch[1] = input[i+14]; ch[2] = 0x00;
  616. j = Hex2int(ch); 
  617. r = (float)j/255.;
  618. ch[0] = input[i+15]; ch[1] = input[i+16]; ch[2] = 0x00;
  619. j = Hex2int(ch); 
  620. g = (float)j/255.;
  621. ch[0] = input[i+17]; ch[1] = input[i+17]; ch[2] = 0x00;
  622. j = Hex2int(ch); 
  623. b = (float)j/255.;
  624. prefs->color[0] = r;
  625. prefs->color[1] = g;
  626. prefs->color[2] = b;
  627. SetTextColor(p,prefs);
  628. }
  629.  
  630. if (input[i] == '!' && input[i+1] == '!')
  631. {
  632. out--;
  633. i--;
  634. while (input[i++] != '>') ;
  635. currentDepth = pointDepthLimit;
  636. goto NewPage; 
  637.  
  638. if (input[i] == '#' && input[i + 1] == '3' && input[i+2] == '0')
  639. goto TheEnd;
  640.  
  641. if (input[i] == 0x2f) 
  642. {
  643. if (input[i+1]=='h' || input[i+1]=='H') {
  644. if (LineSegmented == false) 
  645. {
  646. currentDepth += LeadingValue(p,prefs);
  647. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  648. }
  649. LineSegmented = true;
  650. *(out - 1)=0x00;
  651. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  652. PDF_show(p,(char *)buf);
  653. out = buf;
  654. *out++ = input[i]; 
  655. PDF_set_leading (p, prefs->leading);
  656. PDF_setfont(p,font,prefs->ptsize);
  657.  
  658. if (tolower(input[i+1])=='p' && tolower(input[i+2])=='r'
  659. && tolower(input[i+3])=='e')
  660. {
  661. if (LineSegmented == false) 
  662. {
  663. currentDepth += LeadingValue(p,prefs);
  664. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  665. }
  666. LineSegmented = true;
  667. *(out - 1)=0x00;
  668. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  669. PDF_show(p,(char *)buf);
  670. out = buf;
  671. *out++ = input[i]; 
  672. prefs->font = origBaseFont;
  673. SetStyle(p,prefs);
  674. }
  675.  
  676. if (input[i+1]=='i' || input[i+1]=='I') {
  677. if (LineSegmented == false) 
  678. {
  679. currentDepth += LeadingValue(p,prefs);
  680. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  681. }
  682. LineSegmented = true;
  683. *(out - 1)=0x00;
  684. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  685. PDF_show(p,(char *)buf);
  686. out = buf;
  687. *out++ = input[i]; 
  688. prefs->style &= NOT_ITALIC;
  689. SetStyle(p,prefs);
  690. }
  691.  
  692. if (tolower(input[i+1])=='b' || !strncmp("strong",(char *)(input+i+1),6)
  693. || !strncmp("STRONG",(char *)(input+i+1),6)) {
  694. if (LineSegmented == false) 
  695. {
  696. currentDepth += LeadingValue(p,prefs);
  697. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  698. }
  699. LineSegmented = true;
  700. *(out - 1)=0x00;
  701. soFar += PDF_stringwidth(p,(char *)buf,currentFont,fsize);
  702. PDF_show(p,(char *)buf);
  703. out = buf;
  704. *out++ = input[i]; 
  705. prefs->style &= NOT_BOLDFACE;
  706. SetStyle(p,prefs);
  707. }
  708. out--;
  709. i--;
  710. while (input[i++] != '>') ;
  711.  
  712. if (sendDown == true)
  713. goto TerminateLine;
  714. continue;
  715.  
  716. } while (strchr(okLineEnders,input[i])==NULL && input[i] != CARRIAGE_RETURN
  717. && input[i] != LINEFEED && i < textLength - 2); 
  718. *out++ = input[i++]; 
  719. *out = 0x00;
  720. if (LineSegmented == true)
  721. { PDF_show(p,(char *)buf); goto SegEntry; }
  722. if (prefs->justify == true) 
  723. JustifyLine(p,(char *)buf,prefs,desiredWidth);
  724. else
  725. PDF_set_horiz_scaling(p,(float)prefs->chwidth);
  726. TerminateLine:
  727. *out = 0x00; 
  728. currentDepth += LeadingValue(p,prefs); 
  729.  
  730. SegEntry:
  731. PDF_set_text_pos(p,(float)(prefs->marginLeft),PAGEHEIGHT-currentDepth);
  732. if (LineSegmented == false)
  733. PDF_show(p,(char *)buf);
  734. NewPage:
  735. int curfont = PDF_get_font(p);
  736. float fontsize = PDF_get_fontsize(p);
  737. float lead = LeadingValue(p,prefs);
  738. if ( currentDepth >= pointDepthLimit ) { 
  739. PDF_end_page(p);
  740. timeForNewPage = true;
  741. }
  742. if (timeForNewPage && i < textLength - 1) {
  743. timeForNewPage = false;
  744. PDF_begin_page(p,LETTER_WIDTH,LETTER_HEIGHT); 
  745. PDF_setfont(p,font,prefs->ptsize);
  746. PDF_set_leading(p, prefs->leading);
  747. DoHeader(prefs,p,++page);
  748. SetStyle(p,prefs);
  749. SetTextColor(p,prefs);
  750. currentDepth = LeadingValue(p,prefs) + prefs->marginTop;
  751. PDF_set_text_pos(p,prefs->marginLeft,PAGEHEIGHT - currentDepth);
  752. PDF_show(p," ");
  753. /*timeForNewPage = false;
  754. PDF_setfont(p,curfont,fontsize);
  755. SetStyle(p,prefs);
  756. PDF_set_leading(p,lead);
  757. SetTextColor(p,prefs); 
  758. currentDepth = LeadingValue(p,prefs) + prefs->marginTop;
  759. PDF_set_text_pos(p,prefs->marginLeft,PAGEHEIGHT - currentDepth);
  760. PDF_show(p," "); */
  761. }
  762. lw = 0;
  763. TheEnd:
  764. bbxtDoneProgress(callbacks);
  765. PDF_end_page(p);
  766. PDF_close(p);
  767. HUnlock(theText);
  768. if (fref != -1) {
  769. amt = sizeof(Prefs);
  770. SetEOF(fref,0L);
  771. err = FSWrite(fref,&amt,prefs);
  772. FSClose(fref);
  773. }
  774. if (prefs->launchAcrobat == true) 
  775. OpenInAcrobat(callbacks,w,(char *)filename);
  776. if (prefs) DisposePtr((Ptr)prefs);
  777. return err;}
  778. char *lowerstr( char *p) {
  779. int i;
  780. char *ch = p;
  781. for (i=0; *ch; i++)
  782. ch[i] = tolower(ch[i]);
  783. return p;
  784. }
  785. void FudgeName(ExternalCallbackBlock *cb, unsigned char *str, WindowPtr w) {
  786. Str255 fName;
  787. short v;
  788. long d;
  789. int length;
  790. char ending[] = { '.','p','d','f', 0x00 };
  791. bbxtGetDocInfo(cb,w,fName,&v,&d); 
  792. length = *fName;
  793. BlockMove(fName+1,str,(long) *fName);
  794. BlockMove(ending,str+length,5);
  795. }
  796. void OpenInAcrobat(ExternalCallbackBlock *cb,WindowPtr w, char *pdfFileName) {
  797. Str255 fName;
  798. short v;
  799. long d;
  800. FSSpec fss,appFSS;
  801. ProcessSerialNumber psn;
  802. extern void CopyCtoP( char *c, Str63 p);
  803. OSErr err = noErr;
  804. bbxtGetDocInfo(cb,w,fName,&v,&d); 
  805. CopyCtoP(pdfFileName,fName);
  806. FSMakeFSSpec(0,0L,fName,&fss);
  807. bbxtFindApplication(cb,'CARO', &appFSS);
  808. err = bbxtLaunchApplication(cb,'CARO',&appFSS,&psn);
  809. bbxtSendOpenDoc(cb,'CARO', nil, &fss,true);
  810. }
  811. void setDefaultPrefs( PrefsPtr p ) {
  812. p->marginTop = p->marginBot = 72;
  813. p->marginLeft = p->marginRt = 72;
  814. p->font = 5;
  815. p->transition = 6;
  816. p->chwidth = 100;
  817. strcpy(( char *)p->author,"Whomever");
  818. strcpy(( char *)p->title,"Whatever");
  819. strcpy(( char *)p->keywords,"Whichever");
  820. p->justify = false;
  821. p->header = false;
  822. p->numberPages = false;
  823. p->launchAcrobat = true;
  824. p->interpHTML = true;
  825. p->spaces = 5;
  826. p->lines = 60;
  827. p->ptsize = 10.5;
  828. p->leading = 11.5;
  829. p->color[0] = p->color[1] = p->color[2] = 0.0;
  830. p->style = 0;
  831. }
  832. float LeadingValue(PDF *p,PrefsPtr prefs) {
  833. float fntsize = PDF_get_fontsize(p);
  834. if (fntsize == prefs->ptsize)
  835. return prefs->leading;
  836. return fntsize;
  837. }
  838. void SetTextColor(PDF *p, PrefsPtr prefs ) {
  839. PDF_setrgbcolor(p,prefs->color[0],prefs->color[1],prefs->color[2]);
  840. }
  841.  
  842. void SetStyle(PDF *p, PrefsPtr prefs)
  843. {
  844. int baseFamily = (prefs->font - 1)/4;
  845. int curFont = PDF_get_font(p);
  846. int newFont,fnt,i;
  847. float fontsize = PDF_get_fontsize(p);
  848.  
  849. newFont = 1 + ((baseFamily * 4) | prefs->style);
  850. fnt = PDF_findfont(p,(char *)fontTable[newFont],"default",0); 
  851. PDF_setfont(p, fnt, fontsize);
  852. }
  853. void JustifyLine(PDF *p, char *line, PrefsPtr pp,long targetWidth) {
  854. float lw,rawRatio,amt_per_char;
  855. int font = PDF_get_font(p);
  856. float fontsize = PDF_get_fontsize(p);
  857. char *buf = line;
  858. int chars,words;
  859. lw = PDF_stringwidth(p,buf,font,fontsize);
  860. rawRatio = pp->chwidth/100.;
  861. lw *= rawRatio;
  862. if (lw < 0.6 * targetWidth) {
  863. PDF_set_horiz_scaling(p, pp->chwidth);
  864. return; 
  865. }
  866. rawRatio = lw/targetWidth;
  867. chars = CountChars(line);
  868. if (!chars) return;
  869. lw = targetWidth - lw;
  870. lw *= 100./pp->chwidth;
  871. PDF_set_horiz_scaling(p, pp->chwidth * (1. + .11 * lw/targetWidth) );
  872. amt_per_char = .9 * (lw)/chars;
  873. PDF_set_char_spacing(p, (float)((lw > 1.) ? -amt_per_char:amt_per_char));
  874. }
  875. int CountChars(char *line) {
  876. char *b = line;
  877. int i = 0;
  878. while (*b) {
  879. i++;
  880. b++;
  881. }
  882. return i;
  883. }
  884. int CountWords(char *line) {
  885. char *b = line;
  886. int i = 0;
  887. while (*b) {
  888. if (*b == SPACE) {
  889. while (*b++ == SPACE) ;
  890. if (*b == NULL) break;
  891. }
  892. i++;
  893. b++;
  894. }
  895. return i;
  896. }
  897. void DoHeader(PrefsPtr prefs, PDF *p, long page) {
  898. float x,y,fs = PDF_get_font(p);
  899. char tmp[2];
  900. if (prefs->numberPages) {
  901. x = PAGEWIDTH - prefs->marginRt;
  902. y = PAGEHEIGHT - (.6 * prefs->marginTop);
  903. PDF_set_text_pos(p,x,y);
  904. sprintf((char *)tmp,"%i",(int)page);
  905. PDF_show(p,tmp);
  906. }
  907. if (prefs->header == false) return;
  908. PDF_setfont(p,fs,0.9 * prefs->ptsize);
  909. x = prefs->marginLeft;
  910. y = PAGEHEIGHT - (.6 * prefs->marginTop);
  911. PDF_set_text_pos(p,x,y);
  912. PDF_show(p,(char *)prefs->author);
  913. y -= 0.9 * prefs->leading;
  914. PDF_set_text_pos(p,x,y);
  915. PDF_show(p,(char *)prefs->title);
  916. y -= 0.9 * prefs->leading;
  917. PDF_set_text_pos(p,x,y);
  918. PDF_show(p,(char *)prefs->keywords);
  919. PDF_setfont(p,fs,prefs->ptsize);
  920. }
  921. int Hex2int(char *c) {
  922. char ch[2];
  923. int value = 0;
  924. ch[0] = *c; ch[1] = 0x00;
  925. if (isdigit(ch[0])) value = 16 * atoi(ch);
  926. else {
  927. if (tolower(ch[0]) == 'a') value = 16 * 10;
  928. if (tolower(ch[0]) == 'b') value = 16 * 11;
  929. if (tolower(ch[0]) == 'c') value = 16 * 12;
  930. if (tolower(ch[0]) == 'd') value = 16 * 13;
  931. if (tolower(ch[0]) == 'e') value = 16 * 14;
  932. if (tolower(ch[0]) == 'f') value = 16 * 15;
  933. }
  934. ch[0] = *(c+1);
  935. if (isdigit(ch[0])) value += atoi(ch);
  936. else {
  937. if (tolower(ch[0]) == 'a') value += 10;
  938. if (tolower(ch[0]) == 'b') value += 11;
  939. if (tolower(ch[0]) == 'c') value += 12;
  940. if (tolower(ch[0]) == 'd') value += 13;
  941. if (tolower(ch[0]) == 'e') value += 14;
  942. if (tolower(ch[0]) == 'f') value += 15;
  943. }
  944. return value;
  945. }
  946.